package com.livestocksolutions.ui;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.Calendar;
import java.util.Date;

import com.livestocksolutions.Observation;
import com.livestocksolutions.interfaces.Observable;
import com.livestocksolutions.util.JDatePickerDate;

import javax.swing.JSeparator;
import javax.swing.DropMode;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;

/**
 * Create and show an Observation, and allow modifying some of the contents.
 * @author Ken DeVries
 * @author Adam Parr
 * 
 * @.modified 19 March 2013
 */
public class ObservationFrame extends JFrame {
	private static final long serialVersionUID = 1L;
	
	protected JDatePickerDate observationDate;
	protected JComboBox statusCB;
	protected JTextArea txtDescription;
	
	/**
	 * This class will show a Frame of each type of Observation.
	 * @param parent The Observable that will have this observation.
	 * @param observation The Observation to be passed in. Pass in <tt>null</tt> if this is a new observation.
	 * @param title The title that will identify the Observable to the user.
	 */
	public ObservationFrame(Observable parent, Observation observation, String title){
		createFrame(parent,observation,title);
	}
	
	/**
	 * This class will show a Frame of each type of Observation.
	 * @param parent The object that will have this observation.
	 * @param observation The Observation to be passed in. Pass in <tt>null</tt> if this is a new observation.
	 * @param title The title that will identify the Observable to the user.
	 */
	protected void createFrame(final Observable parent, final Observation observation, final String title){
		setAlwaysOnTop(true);
		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		setIconImage(MainFrame.getImage(MainFrame.OBSERVATION_LIST));
		
		observationDate = JDatePickerDate.createJDatePicker();
		
		//declaring all variables at the top, as the following if statements may change the text of some of the components
		observationDate.setTextEditable(observation==null);
		// Disable if this Observation is existing.
		observationDate.setEnabled(observation==null);
		Calendar cal = Calendar.getInstance();
		cal.setTime(observation!=null?observation.getDate():new Date());
		observationDate.setValue(cal);
		
		observationDate.setTextEditable(observation==null);
		for(Component c : observationDate.getComponents()){
			c.setEnabled(observation==null);
		}
		
		getContentPane().setLayout(new BorderLayout(0, 5));
				
		JPanel northPanel = new JPanel();
		northPanel.setBorder(new EmptyBorder(5,5,5,5));
		getContentPane().add(northPanel, BorderLayout.NORTH);
		northPanel.setLayout(new BorderLayout(0, 5));
		JLabel lblAddObservation = new JLabel();
		
		
		//Check to see if the passed in argument 
		lblAddObservation.setText((observation!=null?"Updating":"Adding")+" an observation to " + title);
		JPanel flow =new JPanel();
		flow.add(lblAddObservation);
		setTitle(lblAddObservation.getText());
		JPanel observationPanel = new JPanel();
		northPanel.add(observationPanel, BorderLayout.NORTH);
		observationPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
		
		observationPanel.add(flow);
		
		JPanel dateStatusPanel = new JPanel();
		northPanel.add(dateStatusPanel, BorderLayout.CENTER);
		dateStatusPanel.setLayout(new BorderLayout(5, 5));
		
		JPanel datePanel = new JPanel();
		dateStatusPanel.add(datePanel, BorderLayout.WEST);
		datePanel.setLayout(new BorderLayout(5, 0));
		
		datePanel.add(new JLabel("Date:"), BorderLayout.WEST);
		datePanel.add(observation!=null?new JLabel(JDatePickerDate.format(observation.getDate())):observationDate,BorderLayout.CENTER);
		
		statusCB = new JComboBox(new String[]{Observation.getPriorityString(Observation.RESOLVED),Observation.getPriorityString(Observation.OBSERVE),Observation.getPriorityString(Observation.NONCRITICAL),Observation.getPriorityString(Observation.WATCH),Observation.getPriorityString(Observation.CRITICAL),Observation.getPriorityString(Observation.URGENT)});
		
		JPanel statusPanel = new JPanel();
		dateStatusPanel.add(statusPanel, BorderLayout.EAST);
		statusPanel.setLayout(new BorderLayout(5, 0));
		
		statusPanel.add(new JLabel("Status:"), BorderLayout.WEST);
		
		statusPanel.add(statusCB);
		
		JPanel southPanel = new JPanel();
		southPanel.setBorder(new EmptyBorder(0,5,0,5));
		getContentPane().add(southPanel, BorderLayout.CENTER);
		southPanel.setLayout(new BorderLayout(0, 5));
		
		txtDescription = new JTextArea();
		txtDescription.setDropMode(DropMode.INSERT);
		txtDescription.setWrapStyleWord(true);
		txtDescription.setLineWrap(true);
		txtDescription.setRows(3);
		txtDescription.setColumns(10);
		
		JPanel descriptionPanel = new JPanel();
		southPanel.add(descriptionPanel, BorderLayout.CENTER);
		descriptionPanel.setLayout(new BorderLayout(5, 0));
		
		descriptionPanel.add(new JLabel("Description"), BorderLayout.NORTH);
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setViewportView(txtDescription);
		scrollPane.setViewportBorder(null);
		descriptionPanel.add(scrollPane, BorderLayout.CENTER);

		JSeparator separator = new JSeparator();
		southPanel.add(separator, BorderLayout.SOUTH);
		JButton btnCreateOrUpdate = new JButton(observation==null?"Create":"Save");
		
		btnCreateOrUpdate.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				Date date = observationDate.getDate();
				if(date==null && observation==null){
					JOptionPane.showMessageDialog(ObservationFrame.this,"A date must be set for observation.","Can not save Observation", JOptionPane.OK_OPTION);
					return;
				}
				
				Observation newObservation=observation!=null?observation:new Observation(date,txtDescription.getText(),statusCB.getSelectedIndex());
				newObservation.setPriority(statusCB.getSelectedIndex());
				newObservation.setComment(txtDescription.getText());

				parent.addObservation(newObservation);
				
				dispose();
			}
		});
		
		JPanel buttonPanel = new JPanel();
		getContentPane().add(buttonPanel, BorderLayout.SOUTH);
		FlowLayout flowLayout = (FlowLayout) buttonPanel.getLayout();
		flowLayout.setAlignment(FlowLayout.RIGHT);
		
		JButton btnClear = new JButton("Clear");
		btnClear.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				setTextInFields(observation);
			}
		});
		buttonPanel.add(btnClear);
		buttonPanel.add(btnCreateOrUpdate);
		
		setTextInFields(observation);
		pack();
		setLocationRelativeTo(MainFrame.getInstance());
		setVisible(true);
	}
	
	/**
	 * Set the text in the fields
	 * @param observation
	 */
	private void setTextInFields(Observation observation){
		Calendar cal = Calendar.getInstance();
		if(observation!=null){
			cal.setTime(observation.getDate());
		}
		observationDate.setValue(cal);
		observationDate.getModel().setDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE));
		statusCB.setSelectedIndex(observation!=null?observation.getPriority():Observation.OBSERVE);
		txtDescription.setText(observation!=null?observation.getComment():"");
	}
	
	@Override
	public void dispose(){
		for(WindowListener wl : getWindowListeners()){
			wl.windowClosing(new WindowEvent(this,WindowEvent.WINDOW_CLOSING));
		}
		
		super.dispose();
	}
}
